﻿using System;
using System.Collections;
using System.IO;

namespace Zjh.PackSerializer.Converters.Base
{
    public class ListConverter : PackConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return typeof(IList).IsAssignableFrom(objectType);
        }

        public override bool Read(Stream stream, Type objectType, IPackSerializer serializer, out object output)
        {
            // 长度
            var lengthBuffer = new byte[4];
            stream.Read(lengthBuffer, 0, lengthBuffer.Length);
            int len = BitConverter.ToInt32(lengthBuffer, 0);

            IList list = null;
            if (objectType.IsGenericType)
            {
                var genericType = objectType.GetGenericTypeDefinition();
                var instanceType = genericType.MakeGenericType(objectType.GetGenericArguments());
                list = (IList)Activator.CreateInstance(instanceType, len);
            }
            else
            {
                list = (IList)Activator.CreateInstance(objectType, len);
            }

            Type itemType;
            if (objectType.IsGenericType)
            {
                itemType = objectType.GetGenericArguments()[0];
            }
            else
            {
                itemType = objectType.GetElementType();
            }
            for (int i = 0; i < len; i++)
            {
                object item = null;
                item = serializer.Deserialize(stream, itemType);
                if (objectType.IsGenericType)
                {
                    list.Add(item);
                }
                else
                {
                    list[i] = item;
                }

            }
            output = list;
            return true;
        }

        public override bool Write(Stream stream, Type objectType, object input, IPackSerializer serializer)
        {
            var list = input as IList;
            int len = list == null ? 0 : list.Count;
            var lengthBuffer = BitConverter.GetBytes(len);
            stream.Write(lengthBuffer, 0, lengthBuffer.Length);
            if (list != null)
            {
                foreach (var item in list)
                {
                    serializer.Serialize(stream, item.GetType(), item);
                }
            }
            return true;
        }
    }
}